#region Using References

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Beaker.Services.FileSystem;
using Beaker.Services.Locator;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using FileSystemService = Beaker.Services.FileSystem.Physical.FileSystemService;

#endregion

namespace Beaker.OpenCube.Specs.Services
{
	[ExcludeFromCodeCoverage]
	[TestClass]
	public class ManualServiceLocatorSpecs
	{
		[TestMethod]
		public void OnlySingleServiceOfTypeWithSameNameCanBeRegistered()
		{
			// arrange
			var locator = new ManualServiceLocator();
			locator.RegisterSingletonService( new FileSystemService() );

			// act
			Action registerSecond = () => locator.RegisterSingletonService( new FileSystemService() );

			// assert
			registerSecond.ShouldThrow<InvalidOperationException>();
		}

		[TestMethod]
		public void MultipleServicesOfSameTypeWithDifferentNamesCanBeRegistered()
		{
			// arrange
			var locator = new ManualServiceLocator();
			locator.RegisterSingletonService( new FileSystemService() );

			// act
			Action registerSecond = () => locator.RegisterSingletonService( "Other", new FileSystemService() );

			// assert
			registerSecond.ShouldNotThrow<InvalidOperationException>();
		}

		[TestMethod]
		public void WhenMultipleServicesOfSameTypeWithDifferentNamesAreRegisteredGettingServiceWithoutNameStillReturnsNull()
		{
			// arrange
			var locator = new ManualServiceLocator();
			locator.RegisterSingletonService( "Foo", new FileSystemService() );
			locator.RegisterSingletonService( "Bar", new FileSystemService() );

			// act
			var service = locator.GetInstance<IFileSystemService>();

			// assert
			service.Should().BeNull();
		}

		[TestMethod]
		public void WhenMultipleServicesOfSameTypeWithDifferentNamesAreRegisteredGettingServiceWithCorrectNameReturnsOnlyThatService()
		{
			// arrange
			var locator = new ManualServiceLocator();
			var service1 = new FileSystemService();
			var service2 = new FileSystemService();
			locator.RegisterSingletonService<IFileSystemService>( "Foo", service1 );
			locator.RegisterSingletonService<IFileSystemService>( "Bar", service2 );

			// act
			var service = locator.GetInstance<IFileSystemService>( "Bar" );

			// assert
			service.Should().Be( service2 );
		}

		[TestMethod]
		public void WhenMultipleServicesOfSameTypeWithDifferentNamesAreRegisteredGettingAllOfTypes()
		{
			// arrange
			var locator = new ManualServiceLocator();
			var service1 = new FileSystemService();
			var service2 = new FileSystemService();
			locator.RegisterSingletonService<IFileSystemService>( "Foo", service1 );
			locator.RegisterSingletonService<IFileSystemService>( "Bar", service2 );

			// act
			IEnumerable<IFileSystemService> services = locator.GetAllInstances<IFileSystemService>();

			// assert
			services.Should().Contain( new[] { service1, service2 } );
		}
	}
}